﻿#region Copyright information
// 
// Copyright © 2005-2013 Yongkee Cho. All rights reserved.
// 
// This code is a part of the Biological Object Library and governed under the terms of the
// GNU Lesser General  Public License (LGPL) version 2.1 which accompanies this distribution.
// For more information on the LGPL, please visit http://bol.codeplex.com/license.
// 
// - Filename: Codon.cs
// - Author: Yongkee Cho
// - Email: yongkeecho@gmail.com
// - Date Created: 2013-01-25 3:25 PM
// - Last Modified: 2013-01-25 3:59 PM
// 
#endregion
using System;

namespace BOL.Models.Seq
{
    public struct Codon : IEquatable<Codon>
    {
        #region CodonType enum

        public enum CodonType
        {
            Coding,
            Start,
            Stop
        }

        #endregion

        #region Private variables

        private readonly char _base1;
        private readonly char _base2;
        private readonly char _base3;
        private readonly CodonType _type;

        #endregion

        #region Public properties

        public char Base1 { get { return _base1; } }
        public char Base2 { get { return _base2; } }
        public char Base3 { get { return _base3; } }
        public CodonType Type { get { return _type; } }

        #endregion

        #region Constructors

        public Codon(char base1, char base2, char base3, CodonType type)
        {
            _base1 = base1;
            _base2 = base2;
            _base3 = base3;
            _type = type;
        }

        public Codon(char[] codon, CodonType type)
            : this(codon[0], codon[1], codon[2], type)
        {
            if (codon.Length != 3)
                throw new ArgumentException();
        }

        public Codon(char base1, char base2, char base3)
            : this(base1, base2, base3, CodonType.Coding) { }

        #endregion

        #region IEquatable<Codon> implementation

        public bool Equals(Codon other)
        {
            return _base1.Equals(other._base1) &
                _base2.Equals(other._base2) &
                _base3.Equals(other._base3);
        }

        public bool Equals(char[] other)
        {
            if (other.Length != 3)
                return false;

            return _base1.Equals(other[0]) &
                _base2.Equals(other[1]) &
                _base3.Equals(other[2]);
        }

        #endregion

        #region Object overriden

        public override int GetHashCode()
        {
            return Base1.GetHashCode() ^ Base2.GetHashCode() ^ Base3.GetHashCode();
        }

        public override string ToString()
        {
            return new String(new[]{_base1, _base2, _base3});
        }

        #endregion
    }
}
